[POWERPC][XEN] Track the Hard CPUID as configured by the FW
authorJimi Xenidis <jimix@watson.ibm.com>
Mon, 18 Sep 2006 13:23:51 +0000 (09:23 -0400)
committerJimi Xenidis <jimix@watson.ibm.com>
Mon, 18 Sep 2006 13:23:51 +0000 (09:23 -0400)
This patch correctly implements and supports hard_smp_processor_id().

Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
xen/arch/powerpc/boot_of.c
xen/arch/powerpc/powerpc64/ppc970.c
xen/arch/powerpc/setup.c
xen/include/asm-powerpc/powerpc64/procarea.h
xen/include/asm-powerpc/processor.h
xen/include/asm-powerpc/smp.h

index eca84665fdfaf63e741d3a5f2559f84c90499ff9..f80e1074ff873b5e4948c28f5e68e918dde1cf44 100644 (file)
@@ -957,21 +957,31 @@ static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
 
 static int __init boot_of_cpus(void)
 {
-    int cpus;
-    int cpu, bootcpu, logical;
+    int cpus_node;
+    int cpu_node, bootcpu_node, logical;
     int result;
+    s32 cpuid;
     u32 cpu_clock[2];
+    extern uint cpu_hard_id[NR_CPUS];
 
-    cpus = of_finddevice("/cpus");
-    cpu = of_getchild(cpus);
-    result = of_getprop(cpu, "timebase-frequency", &timebase_freq,
+    /* Look up which CPU we are running on right now and get all info
+     * from there */
+    result = of_getprop(bof_chosen, "cpu",
+                        &bootcpu_node, sizeof (bootcpu_node));
+    if (result == OF_FAILURE)
+        of_panic("Failed to look up boot cpu\n");
+
+    cpu_node = bootcpu_node;
+
+    result = of_getprop(cpu_node, "timebase-frequency", &timebase_freq,
             sizeof(timebase_freq));
     if (result == OF_FAILURE) {
         of_panic("Couldn't get timebase frequency!\n");
     }
     of_printf("OF: timebase-frequency = %d Hz\n", timebase_freq);
 
-    result = of_getprop(cpu, "clock-frequency", &cpu_clock, sizeof(cpu_clock));
+    result = of_getprop(cpu_node, "clock-frequency",
+                        &cpu_clock, sizeof(cpu_clock));
     if (result == OF_FAILURE || (result !=4 && result != 8)) {
         of_panic("Couldn't get clock frequency!\n");
     }
@@ -983,69 +993,79 @@ static int __init boot_of_cpus(void)
     cpu_khz /= 1000;
     of_printf("OF: clock-frequency = %ld KHz\n", cpu_khz);
 
-    /* Look up which CPU we are running on right now.  */
-    result = of_getprop(bof_chosen, "cpu", &bootcpu, sizeof (bootcpu));
-    if (result == OF_FAILURE)
-        of_panic("Failed to look up boot cpu\n");
-
-    cpu = of_getpeer(cpu);
-
-    /* We want a continuous logical cpu number space.  */
+    /* We want a continuous logical cpu number space and we'll make
+     * the booting CPU logical 0.  */
     cpu_set(0, cpu_present_map);
     cpu_set(0, cpu_online_map);
     cpu_set(0, cpu_possible_map);
 
-    /* Spin up all CPUS, even if there are more than NR_CPUS, because
-     * Open Firmware has them spinning on cache lines which will
-     * eventually be scrubbed, which could lead to random CPU activation.
-     */
-    for (logical = 1; cpu > 0; logical++) {
-        unsigned int cpuid, ping, pong;
-        unsigned long now, then, timeout;
-
-        if (cpu == bootcpu) {
-            of_printf("skipping boot cpu!\n");
-            continue;
-        }
+    result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid));
+    cpu_hard_id[0] = cpuid;
 
-        result = of_getprop(cpu, "reg", &cpuid, sizeof(cpuid));
-        if (result == OF_FAILURE)
-            of_panic("cpuid lookup failed\n");
+    /* Spin up all CPUS, even if there are more than NR_CPUS or we are
+     * runnign nosmp, because Open Firmware has them spinning on cache
+     * lines which will eventually be scrubbed, which could lead to
+     * random CPU activation.
+     */
 
-        of_printf("spinning up secondary processor #%d: ", logical);
+    /* Find the base of the multi-CPU package node */
+    cpus_node = of_finddevice("/cpus");
+    if (cpus_node <= 0) {
+        of_printf("Single Processor System\n");
+        return 1;
+    }
+    /* Start with the first child */
+    cpu_node = of_getchild(cpus_node);
 
-        __spin_ack = ~0x0;
-        ping = __spin_ack;
-        pong = __spin_ack;
-        of_printf("ping = 0x%x: ", ping);
+    for (logical = 1; cpu_node > 0; logical++) {
+        unsigned int ping, pong;
+        unsigned long now, then, timeout;
+        
+        if (cpu_node == bootcpu_node) {
+            /* same CPU as boot CPU shich we have already made 0 so
+             * reduce the logical count */
+            --logical;
+        } else {
+            result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid));
+            if (result == OF_FAILURE)
+                of_panic("cpuid lookup failed\n");
 
-        mb();
-        result = of_start_cpu(cpu, (ulong)spin_start, logical);
-        if (result == OF_FAILURE)
-            of_panic("start cpu failed\n");
+            cpu_hard_id[logical] = cpuid;
 
-        /* We will give the secondary processor five seconds to reply.  */
-        then = mftb();
-        timeout = then + (5 * timebase_freq);
+            of_printf("spinning up secondary processor #%d: ", logical);
 
-        do {
-            now = mftb();
-            if (now >= timeout) {
-                of_printf("BROKEN: ");
-                break;
-            }
+            __spin_ack = ~0x0;
+            ping = __spin_ack;
+            pong = __spin_ack;
+            of_printf("ping = 0x%x: ", ping);
 
             mb();
-            pong = __spin_ack;
-        } while (pong == ping);
-        of_printf("pong = 0x%x\n", pong);
+            result = of_start_cpu(cpu_node, (ulong)spin_start, logical);
+            if (result == OF_FAILURE)
+                of_panic("start cpu failed\n");
+
+            /* We will give the secondary processor five seconds to reply.  */
+            then = mftb();
+            timeout = then + (5 * timebase_freq);
+
+            do {
+                now = mftb();
+                if (now >= timeout) {
+                    of_printf("BROKEN: ");
+                    break;
+                }
 
-        if (pong != ping) {
-            cpu_set(logical, cpu_present_map);
-            cpu_set(logical, cpu_possible_map);
-        }
+                mb();
+                pong = __spin_ack;
+            } while (pong == ping);
+            of_printf("pong = 0x%x\n", pong);
 
-        cpu = of_getpeer(cpu);
+            if (pong != ping) {
+                cpu_set(logical, cpu_present_map);
+                cpu_set(logical, cpu_possible_map);
+            }
+        }
+        cpu_node = of_getpeer(cpu_node);
     }
     return 1;
 }
index 06fd0b63e6cfe0ebedecc8b6371af6d34a91e393..e59571bd35258d5745345849606c15316c89ec82 100644 (file)
@@ -145,7 +145,7 @@ void cpu_initialize(int cpuid)
     mthsprg0((ulong)parea); /* now ready for exceptions */
 
     printk("CPU[PIR:%u IPI:%u Logical:%u] Hello World!\n",
-           mfpir(), raw_smp_processor_id(), smp_processor_id());
+           mfpir(), hard_smp_processor_id(), smp_processor_id());
 
 #ifdef DEBUG
     {
index 1350a637017d82bad0800b87a857694e817b2f74..eb75a30bd4db246101017624ab7749903abc666e 100644 (file)
@@ -74,6 +74,7 @@ ulong oftree;
 ulong oftree_len;
 ulong oftree_end;
 
+uint cpu_hard_id[NR_CPUS] __initdata;
 cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
 cpumask_t cpu_online_map; /* missing ifdef in schedule.c */
 cpumask_t cpu_present_map;
@@ -227,6 +228,7 @@ static void init_parea(int cpuid)
               __func__, STACK_ORDER, cpuid);
 
     pa->whoami = cpuid;
+    pa->hard_id = cpu_hard_id[cpuid];
     pa->hyp_stack_base = (void *)((ulong)stack + STACK_SIZE);
 
     /* This store has the effect of invoking secondary_cpu_init.  */
index 11f91b67e6edee3ef48fe25187f4f7e780fddfef..def6fe71e5877992923eb89cae3dd0c8125671c8 100644 (file)
@@ -29,6 +29,7 @@ struct gdb_state;
 struct processor_area
 {
     unsigned int whoami;
+    unsigned int hard_id;
     struct vcpu *cur_vcpu;
     void *hyp_stack_base;
     ulong saved_regs[2];
index 3b91f554a6a27ae9e1933782e9c93bf2c1e45b30..d7a296515498c924b9752571d20e98f7586011c4 100644 (file)
@@ -38,7 +38,7 @@ struct domain;
 struct vcpu;
 struct cpu_user_regs;
 extern int cpu_machinecheck(struct cpu_user_regs *);
-extern int cpu_scom_init(void);
+extern void cpu_scom_init(void);
 extern void show_registers(struct cpu_user_regs *);
 extern void show_execution_state(struct cpu_user_regs *);
 extern void show_backtrace(ulong sp, ulong lr, ulong pc);
index 30a585fbbeae086315cc4b6e16244a63bf04b768..9da0ba0804a5ac54f761dea85752e8ecd875ebff 100644 (file)
@@ -28,9 +28,9 @@
 extern int smp_num_siblings;
 
 /* revisit when we support SMP */
-#define get_hard_smp_processor_id(i) (global_cpu_table[i]->whoami)
 #define raw_smp_processor_id() (parea->whoami)
-#define hard_smp_processor_id() raw_smp_processor_id()
+#define get_hard_smp_processor_id(i) (global_cpu_table[i]->hard_id)
+#define hard_smp_processor_id() (parea->hard_id)
 extern cpumask_t cpu_sibling_map[];
 extern cpumask_t cpu_core_map[];
 extern void __devinit smp_generic_take_timebase(void);